package com.kylin.common.saas.datasource;

import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.kylin.common.core.exception.ServiceException;
import com.kylin.common.core.util.SpringUtils;
import com.kylin.common.saas.context.TenantContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;

/**
 * @author wuhao
 * @version 1.0 - 2024/2/23
 */
@Slf4j
//@Aspect
//@Component
public class DataSourceAspect {

//    @Pointcut("execution( * com.kylin.common.core.service.impl.BaseServiceImpl+.*(..)) && !@annotation(com.baomidou.dynamic.datasource.annotation.DS)")
    @Pointcut("within(com.kylin.common.core.service.impl.*) && !@annotation(com.baomidou.dynamic.datasource.annotation.DS)")
    public void dataSourcePointcut() {}

    @Before("dataSourcePointcut()")
    public void doBefore(JoinPoint joinPoint) {
        log.info("========================拦截数据源========================");
        // 获取租户ID
        String tenantId = TenantContextHolder.getContext().getTenantId();
        log.info("当前租户：" + tenantId);
        String master = "master";
        if (StringUtils.isEmpty(tenantId)) {
            String peek = DynamicDataSourceContextHolder.peek();
            if (master.equals(peek)) {
                return;
            }
            DynamicDataSourceContextHolder.push(master);
        } else {
            DataSourceManager dataSourceManager = SpringUtils.getBean(DataSourceManager.class);
            DataSource dataSource = dataSourceManager.getDbSource(tenantId);
            // 如何获取当前数据源呢
            if(dataSource == null) {
                throw new ServiceException("当前租户未配置数据源，请联系管理员！");
            }else {
                DynamicDataSourceContextHolder.push(tenantId);
            }
        }
        Class<?> clazz = joinPoint.getTarget().getClass();
        String methodName = joinPoint.getSignature().getName();
        log.info(clazz + "类-" + methodName + "方法-" + tenantId + "数据源");
        log.info("========================拦截数据源【end】========================");
    }

    @AfterReturning("dataSourcePointcut()")
    public void doAfter(JoinPoint joinPoint) {
        log.info("=====回退数据源");
        DynamicDataSourceContextHolder.poll();
    }
}
